
#include <string.h>
#include <stdlib.h>
#include "common.h"

String* StringCreate(uint32 iInitialCapacity)
{
	String* sString = (String*)malloc(sizeof(String));
	sString->length = 0;
	sString->capacity = iInitialCapacity;
	sString->value = (wchar*)malloc(sizeof(wchar) * iInitialCapacity);
	sString->value[0] = 0;

	return sString;
}

String* StringCreateFromString(String* sString)
{
	String* sNewString = StringCreate(sString->length + 2);
	sNewString->length = sString->length;
	sNewString->hashcode = sString->hashcode;

	memcpy(sNewString->value, sString->value, sizeof(wchar)*(sString->length+1));
	return sNewString;
}

String* StringCreateFromChar(const char* cString)
{
	int32 iLength = strlen(cString) + 1;
	String* sString = StringCreate(iLength + 10);
	wchar* sStringValue = sString->value;

	while (iLength-- > 0) *(sStringValue++) = *(cString++);

	return sString;
}

void StringDelete(String* sString)
{
	free(sString->value);
	free(sString);
}

void StringEnsureCapacity(String* sString, int32 iRequiredLength)
{
	sString->hashcode = 0;
    if((sString->length + iRequiredLength + 1) > sString->capacity)
    {
    	sString->capacity = ((sString->capacity<<1) + iRequiredLength + 1);
    	sString->value = (wchar*)realloc(sString->value, sizeof(wchar) * sString->capacity);
    }
}

int32 StringHashCode(String* sString)
{
	wchar* cStringValue;

	if (sString->hashcode == 0)
	{
		cStringValue = sString->value;
		while(*cStringValue != 0) sString->hashcode = 31 * sString->hashcode + (*(cStringValue++));
	}

    return sString->hashcode;
}

int32 StringCompare(String* sString1, String* sString2)
{
	wchar* sValue1 = sString1->value;
	wchar* sValue2 = sString2->value;

	//If the lengths are not the same then the string is different.
	if (sString1->length != sString2->length) return (sString1->length - sString2->length);

	//Otherwise compare the values of the strings.
	while ((*(sValue1++) == *(sValue2++)) && (*sValue1 != 0)); //{ sValue1++; sValue2++; }

	//If values are 0 then they are the same, otherwise return the difference.
	return (*sValue1 - *sValue2);
}

int32 WCharLength(wchar* sString)
{
	int32 iLength = 0;
	while (*(sString++) != 0) iLength++;
	return iLength;
}

void StringAppend(String* sString, wchar* sValue, ...)
{
	wchar* sStringValue;

	//Get the length of the given value.
	int32 iLength = WCharLength(sValue);

	//Expand the string buffer length if needed to fit the new value.
	StringEnsureCapacity(sString, iLength);

	//Get the last location of the string value buffer to start copying the new string value.
	sStringValue = sString->value + sString->length;

	//Copy the value into the string.
	while (*sValue != 0) *(sStringValue++) = *(sValue++);

	//Update the new length of the string.
	sString->length += iLength;
}

void StringAppendXml(String* sString, wchar* sValue)
{

}

void StringAppendSpace(String* sString, uint32 iCount)
{

}

void StringAppendCharacter(String* sString, int32 iValue)
{
	StringEnsureCapacity(sString, 1);
	sString->value[sString->length] = iValue;
	sString->value[++(sString->length)] = 0;
}















